<?php
/**
*
* @package phpBB3
* @version $Id: functions_applys.php 3 2011-01-18 20:54:14Z benstassart@gmail.com $
* @copyright (c) 2010-2011 Benjamin Stassart
* Based on applys by Barley @ runetotem.eu (http://www.silverflame.net/)
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
*
*/

/**
* @ignore
*/
if (!defined('IN_PHPBB'))
{
	exit;
}

/**
* Submit Application
*/
function submit_apply($mode, $subject, $username, $topic_type, &$poll, &$data, $update_message = true)
{
	global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;

	// We do not handle erasing posts here

	$current_time = time();
	$post_mode = 'post';
	$update_message = true;
	
	// First of all make sure the subject and topic title are having the correct length.
	// To achieve this without cutting off between special chars we convert to an array and then count the elements.
	$subject = truncate_string($subject);
	$data['topic_title'] = truncate_string($data['topic_title']);

	// Collect some basic information about which tables and which rows to update/insert
	$sql_data = $topic_row = array();
	$poster_id = ($mode == 'edit') ? $data['poster_id'] : (int) $user->data['user_id'];

	// This variable indicates if the user is able to post or put into the queue - it is used later for all code decisions regarding approval
	$post_approval = 1;
	
	// Start the transaction here
	$db->sql_transaction('begin');

	// Collect Information
	switch ($post_mode)
	{
		case 'post':
			$sql_data[POSTS_TABLE]['sql'] = array(
				'forum_id'			=> ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
				'poster_id'			=> (int) $user->data['user_id'],
				'icon_id'			=> $data['icon_id'],
				'poster_ip'			=> $user->ip,
				'post_time'			=> $current_time,
				'post_approved'		=> $post_approval,
				'enable_bbcode'		=> $data['enable_bbcode'],
				'enable_smilies'	=> $data['enable_smilies'],
				'enable_magic_url'	=> $data['enable_urls'],
				'enable_sig'		=> $data['enable_sig'],
				'post_username'		=> (!$user->data['is_registered']) ? $username : '',
				'post_subject'		=> $subject,
				'post_text'			=> $data['message'],
				'post_checksum'		=> $data['message_md5'],
				'post_attachment'	=> (!empty($data['attachment_data'])) ? 1 : 0,
				'bbcode_bitfield'	=> $data['bbcode_bitfield'],
				'bbcode_uid'		=> $data['bbcode_uid'],
				'post_postcount'	=> ($auth->acl_get('f_postcount', $data['forum_id'])) ? 1 : 0,
				'post_edit_locked'	=> $data['post_edit_locked']
			);
		break;
	}

	$post_approved = $sql_data[POSTS_TABLE]['sql']['post_approved'];
	$topic_row = array();

	// And the topic ladies and gentlemen
	switch ($post_mode)
	{
		case 'post':
			$sql_data[TOPICS_TABLE]['sql'] = array(
				'topic_poster'				=> (int) $user->data['user_id'],
				'topic_time'				=> $current_time,
				'topic_last_view_time'		=> $current_time,
				'forum_id'					=> ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id'],
				'icon_id'					=> $data['icon_id'],
				'topic_approved'			=> $post_approval,
				'topic_title'				=> $subject,
				'topic_first_poster_name'	=> (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''),
				'topic_first_poster_colour'	=> $user->data['user_colour'],
				'topic_type'				=> $topic_type,
				'topic_time_limit'			=> ($topic_type == POST_STICKY || $topic_type == POST_ANNOUNCE) ? ($data['topic_time_limit'] * 86400) : 0,
				'topic_attachment'			=> (!empty($data['attachment_data'])) ? 1 : 0,
			);

			if (isset($poll['poll_options']) && !empty($poll['poll_options']))
			{
				$poll_start = ($poll['poll_start']) ? $poll['poll_start'] : $current_time;
				$poll_length = $poll['poll_length'] * 86400;
				if ($poll_length < 0)
				{
					$poll_start = $poll_start + $poll_length;
					if ($poll_start < 0)
					{
						$poll_start = 0;
					}
					$poll_length = 1;
				}

				$sql_data[TOPICS_TABLE]['sql'] = array_merge($sql_data[TOPICS_TABLE]['sql'], array(
					'poll_title'		=> $poll['poll_title'],
					'poll_start'		=> $poll_start,
					'poll_max_options'	=> $poll['poll_max_options'],
					'poll_length'		=> $poll_length,
					'poll_vote_change'	=> $poll['poll_vote_change'])
				);
			}

			$sql_data[USERS_TABLE]['stat'][] = "user_lastpost_time = $current_time" . (($auth->acl_get('f_postcount', $data['forum_id']) && $post_approval) ? ', user_posts = user_posts + 1' : '');

			if ($topic_type != POST_GLOBAL)
			{
				if ($post_approval)
				{
					$sql_data[FORUMS_TABLE]['stat'][] = 'forum_posts = forum_posts + 1';
				}
				$sql_data[FORUMS_TABLE]['stat'][] = 'forum_topics_real = forum_topics_real + 1' . (($post_approval) ? ', forum_topics = forum_topics + 1' : '');
			}
		break;
	}

	// Submit new topic
	$sql = 'INSERT INTO ' . TOPICS_TABLE . ' ' .
	$db->sql_build_array('INSERT', $sql_data[TOPICS_TABLE]['sql']);
	$db->sql_query($sql);

	$data['topic_id'] = $db->sql_nextid();

	$sql_data[POSTS_TABLE]['sql'] = array_merge($sql_data[POSTS_TABLE]['sql'], array(
		'topic_id' => $data['topic_id'])
	);
		
	unset($sql_data[TOPICS_TABLE]['sql']);
	
	// Submit new post
	$sql = 'INSERT INTO ' . POSTS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_data[POSTS_TABLE]['sql']);
	$db->sql_query($sql);
	$data['post_id'] = $db->sql_nextid();

	$sql_data[TOPICS_TABLE]['sql'] = array(
		'topic_first_post_id'		=> $data['post_id'],
		'topic_last_post_id'		=> $data['post_id'],
		'topic_last_post_time'		=> $current_time,
		'topic_last_poster_id'		=> (int) $user->data['user_id'],
		'topic_last_poster_name'	=> (!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : ''),
		'topic_last_poster_colour'	=> $user->data['user_colour'],
		'topic_last_post_subject'	=> (string) $subject,
		);

	unset($sql_data[POSTS_TABLE]['sql']); 

	$make_global = false;

	// Update the topics table
	if (isset($sql_data[TOPICS_TABLE]['sql']))
	{
		$sql = 'UPDATE ' . TOPICS_TABLE . '
			SET ' . $db->sql_build_array('UPDATE', $sql_data[TOPICS_TABLE]['sql']) . '
			WHERE topic_id = ' . $data['topic_id'];
		$db->sql_query($sql);
	}

	// Update the posts table
	if (isset($sql_data[POSTS_TABLE]['sql']))
	{
		$sql = 'UPDATE ' . POSTS_TABLE . '
			SET ' . $db->sql_build_array('UPDATE', $sql_data[POSTS_TABLE]['sql']) . '
			WHERE post_id = ' . $data['post_id'];
		$db->sql_query($sql);
	}

	// Update Poll Tables
	if (isset($poll['poll_options']) && !empty($poll['poll_options']))
	{
		$cur_poll_options = array();

		if ($poll['poll_start'] && $mode == 'edit')
		{
			$sql = 'SELECT *
				FROM ' . POLL_OPTIONS_TABLE . '
				WHERE topic_id = ' . (int)$data['topic_id'] . '
				ORDER BY poll_option_id';
			$result = $db->sql_query($sql);

			$cur_poll_options = array();
			while ($row = $db->sql_fetchrow($result))
			{
				$cur_poll_options[] = $row;
			}
			$db->sql_freeresult($result);
		}

		$sql_insert_ary = array();

		for ($i = 0, $size = sizeof($poll['poll_options']); $i < $size; $i++)
		{
			if (strlen(trim($poll['poll_options'][$i])))
			{
				if (empty($cur_poll_options[$i]))
				{
					// If we add options we need to put them to the end to be able to preserve votes...
					$sql_insert_ary[] = array(
						'poll_option_id'	=> (int) sizeof($cur_poll_options) + 1 + sizeof($sql_insert_ary),
						'topic_id'			=> (int) $data['topic_id'],
						'poll_option_text'	=> (string) $poll['poll_options'][$i]
					);
				}
				else if ($poll['poll_options'][$i] != $cur_poll_options[$i])
				{
					$sql = 'UPDATE ' . POLL_OPTIONS_TABLE . "
						SET poll_option_text = '" . $db->sql_escape($poll['poll_options'][$i]) . "'
						WHERE poll_option_id = " . (int)$cur_poll_options[$i]['poll_option_id'] . '
							AND topic_id = ' . (int)$data['topic_id'];
					$db->sql_query($sql);
				}
			}
		}

		$db->sql_multi_insert(POLL_OPTIONS_TABLE, $sql_insert_ary);

		if (sizeof($poll['poll_options']) < sizeof($cur_poll_options))
		{
			$sql = 'DELETE FROM ' . POLL_OPTIONS_TABLE . '
				WHERE poll_option_id > ' . sizeof($poll['poll_options']) . '
					AND topic_id = ' . (int)$data['topic_id'];
			$db->sql_query($sql);
		}

		// If edited, we would need to reset votes (since options can be re-ordered above, you can't be sure if the change is for changing the text or adding an option
		if ($mode == 'edit' && sizeof($poll['poll_options']) != sizeof($cur_poll_options))
		{
			$db->sql_query('DELETE FROM ' . POLL_VOTES_TABLE . ' WHERE topic_id = ' . (int)$data['topic_id']);
			$db->sql_query('UPDATE ' . POLL_OPTIONS_TABLE . ' SET poll_option_total = 0 WHERE topic_id = ' . (int)$data['topic_id']);
		}
	}

	// we need to update the last forum information
	// only applicable if the topic is not global and it is approved
	// we also check to make sure we are not dealing with globaling the latest topic (pretty rare but still needs to be checked)
	if ($topic_type != POST_GLOBAL && !$make_global && ($post_approved || !$data['post_approved']))
	{
		// the last post makes us update the forum table. This can happen if...
		// We make a new topic
		// We reply to a topic
		// We edit the last post in a topic and this post is the latest in the forum (maybe)
		// We edit the only post in the topic
		// We edit the first post in the topic and all the other posts are not approved
		if (($post_mode == 'post' || $post_mode == 'reply') && $post_approved)
		{
			$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . $data['post_id'];
			$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($subject) . "'";
			$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . $current_time;
			$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $user->data['user_id'];
			$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape((!$user->data['is_registered'] && $username) ? $username : (($user->data['user_id'] != ANONYMOUS) ? $user->data['username'] : '')) . "'";
			$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($user->data['user_colour']) . "'";
		}
		else if ($post_mode == 'edit_last_post' || $post_mode == 'edit_topic' || ($post_mode == 'edit_first_post' && !$data['topic_replies']))
		{
			// this does not _necessarily_ mean that we must update the info again,
			// it just means that we might have to
			$sql = 'SELECT forum_last_post_id, forum_last_post_subject
				FROM ' . FORUMS_TABLE . '
				WHERE forum_id = ' . (int) $data['forum_id'];
			$result = $db->sql_query($sql);
			$row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);

			// this post is the latest post in the forum, better update
			if ($row['forum_last_post_id'] == $data['post_id'])
			{
				// If post approved and subject changed, or poster is anonymous, we need to update the forum_last* rows
				if ($post_approved && ($row['forum_last_post_subject'] !== $subject || $data['poster_id'] == ANONYMOUS))
				{
					// the post's subject changed
					if ($row['forum_last_post_subject'] !== $subject)
					{
						$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_subject = \'' . $db->sql_escape($subject) . '\'';
					}

					// Update the user name if poster is anonymous... just in case an admin changed it
					if ($data['poster_id'] == ANONYMOUS)
					{
						$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape($username) . "'";
					}
				}
				else if ($data['post_approved'] !== $post_approved)
				{
					// we need a fresh change of socks, everything has become invalidated
					$sql = 'SELECT MAX(topic_last_post_id) as last_post_id
						FROM ' . TOPICS_TABLE . '
						WHERE forum_id = ' . (int) $data['forum_id'] . '
							AND topic_approved = 1';
					$result = $db->sql_query($sql);
					$row = $db->sql_fetchrow($result);
					$db->sql_freeresult($result);

					// any posts left in this forum?
					if (!empty($row['last_post_id']))
					{
						$sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour
							FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
							WHERE p.poster_id = u.user_id
								AND p.post_id = ' . (int) $row['last_post_id'];
						$result = $db->sql_query($sql);
						$row = $db->sql_fetchrow($result);
						$db->sql_freeresult($result);

						// salvation, a post is found! jam it into the forums table
						$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id'];
						$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
						$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time'];
						$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id'];
						$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
						$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
					}
					else
					{
						// just our luck, the last topic in the forum has just been turned unapproved...
						$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = 0';
						$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = ''";
						$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = 0';
						$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = 0';
						$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = ''";
						$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = ''";
					}
				}
			}
		}
	}
	else if ($make_global)
	{
		// somebody decided to be a party pooper, we must recalculate the whole shebang (maybe)
		$sql = 'SELECT forum_last_post_id
			FROM ' . FORUMS_TABLE . '
			WHERE forum_id = ' . (int) $data['forum_id'];
		$result = $db->sql_query($sql);
		$forum_row = $db->sql_fetchrow($result);
		$db->sql_freeresult($result);

		// we made a topic global, go get new data
		if ($topic_row['topic_type'] != POST_GLOBAL && $topic_type == POST_GLOBAL && $forum_row['forum_last_post_id'] == $topic_row['topic_last_post_id'])
		{
			// we need a fresh change of socks, everything has become invalidated
			$sql = 'SELECT MAX(topic_last_post_id) as last_post_id
				FROM ' . TOPICS_TABLE . '
				WHERE forum_id = ' . (int) $data['forum_id'] . '
					AND topic_approved = 1';
			$result = $db->sql_query($sql);
			$row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);

			// any posts left in this forum?
			if (!empty($row['last_post_id']))
			{
				$sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour
					FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
					WHERE p.poster_id = u.user_id
						AND p.post_id = ' . (int) $row['last_post_id'];
				$result = $db->sql_query($sql);
				$row = $db->sql_fetchrow($result);
				$db->sql_freeresult($result);

				// salvation, a post is found! jam it into the forums table
				$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id'];
				$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
				$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time'];
				$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id'];
				$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
				$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
			}
			else
			{
				// just our luck, the last topic in the forum has just been globalized...
				$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = 0';
				$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = ''";
				$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = 0';
				$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = 0';
				$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = ''";
				$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = ''";
			}
		}
		else if ($topic_row['topic_type'] == POST_GLOBAL && $topic_type != POST_GLOBAL && $forum_row['forum_last_post_id'] < $topic_row['topic_last_post_id'])
		{
			// this post has a higher id, it is newer
			$sql = 'SELECT p.post_id, p.post_subject, p.post_time, p.poster_id, p.post_username, u.user_id, u.username, u.user_colour
				FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
				WHERE p.poster_id = u.user_id
					AND p.post_id = ' . (int) $topic_row['topic_last_post_id'];
			$result = $db->sql_query($sql);
			$row = $db->sql_fetchrow($result);
			$db->sql_freeresult($result);

			// salvation, a post is found! jam it into the forums table
			$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_id = ' . (int) $row['post_id'];
			$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_post_subject = '" . $db->sql_escape($row['post_subject']) . "'";
			$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_post_time = ' . (int) $row['post_time'];
			$sql_data[FORUMS_TABLE]['stat'][] = 'forum_last_poster_id = ' . (int) $row['poster_id'];
			$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_name = '" . $db->sql_escape(($row['poster_id'] == ANONYMOUS) ? $row['post_username'] : $row['username']) . "'";
			$sql_data[FORUMS_TABLE]['stat'][] = "forum_last_poster_colour = '" . $db->sql_escape($row['user_colour']) . "'";
		}
	}

	// topic sync time!
	// simply, we update if it is a reply or the last post is edited
	

	// Update total post count, do not consider moderated posts/topics
	if ($post_approval)
	{
		if ($post_mode == 'post')
		{
			set_config_count('num_topics', 1, true);
			set_config_count('num_posts', 1, true);
		}
	}

	// Update forum stats
	$where_sql = array(POSTS_TABLE => 'post_id = ' . (int)$data['post_id'], TOPICS_TABLE => 'topic_id = ' . $data['topic_id'], FORUMS_TABLE => 'forum_id = ' . (int)$data['forum_id'], USERS_TABLE => 'user_id = ' . (int)$poster_id);

	foreach ($sql_data as $table => $update_ary)
	{
		if (isset($update_ary['stat']) && implode('', $update_ary['stat']))
		{
			$sql = "UPDATE $table SET " . implode(', ', $update_ary['stat']) . ' WHERE ' . $where_sql[$table];
			$db->sql_query($sql);
		}
	}

	// Delete topic shadows (if any exist). We do not need a shadow topic for an global announcement
	if ($make_global)
	{
		$sql = 'DELETE FROM ' . TOPICS_TABLE . '
			WHERE topic_moved_id = ' . (int)$data['topic_id'];
		$db->sql_query($sql);
	}

	// Committing the transaction before updating search index
	$db->sql_transaction('commit');

	// Delete draft if post was loaded...
	$draft_id = request_var('draft_loaded', 0);
	if ($draft_id)
	{
		$sql = 'DELETE FROM ' . DRAFTS_TABLE . "
			WHERE draft_id = " . (int)$draft_id ."
			AND user_id = " . (int)$user->data['user_id'];
		$db->sql_query($sql);
	}

	// Index message contents
	if ($update_message && $data['enable_indexing'])
	{
		// Select the search method and do some additional checks to ensure it can actually be utilised
		$search_type = basename($config['search_type']);

		if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx))
		{
			trigger_error('NO_SUCH_SEARCH_MODULE');
		}

		if (!class_exists($search_type))
		{
			include("{$phpbb_root_path}includes/search/$search_type.$phpEx");
		}

		$error = false;
		$search = new $search_type($error);

		if ($error)
		{
			trigger_error($error);
		}

		$search->index($mode, $data['post_id'], $data['message'], $subject, $poster_id, ($topic_type == POST_GLOBAL) ? 0 : $data['forum_id']);
	}

	// Topic Notification, do not change if moderator is changing other users posts...
	if ($user->data['user_id'] == $poster_id)
	{
		if (!$data['notify_set'] && $data['notify'])
		{
			$sql = 'INSERT INTO ' . TOPICS_WATCH_TABLE . ' (user_id, topic_id)
				VALUES (' . (int)$user->data['user_id'] . ', ' . (int)$data['topic_id'] . ')';
			$db->sql_query($sql);
		}
		else if ($data['notify_set'] && !$data['notify'])
		{
			$sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . '
				WHERE user_id = ' . (int)$user->data['user_id'] . '
					AND topic_id = ' . (int)$data['topic_id'];
			$db->sql_query($sql);
		}
	}

	if ($mode == 'post' || $mode == 'reply' || $mode == 'quote')
	{
		// Mark this topic as posted to
		markread('post', $data['forum_id'], $data['topic_id'], $data['post_time']);
	}

	// Mark this topic as read
	// We do not use post_time here, this is intended (post_time can have a date in the past if editing a message)
	markread('topic', $data['forum_id'], $data['topic_id'], time());

	//
	if ($config['load_db_lastread'] && $user->data['is_registered'])
	{
		$sql = 'SELECT mark_time
			FROM ' . FORUMS_TRACK_TABLE . '
			WHERE user_id = ' . (int)$user->data['user_id'] . '
				AND forum_id = ' . (int)$data['forum_id'];
		$result = $db->sql_query($sql);
		$f_mark_time = (int) $db->sql_fetchfield('mark_time');
		$db->sql_freeresult($result);
	}
	else if ($config['load_anon_lastread'] || $user->data['is_registered'])
	{
		$f_mark_time = false;
	}

	if (($config['load_db_lastread'] && $user->data['is_registered']) || $config['load_anon_lastread'] || $user->data['is_registered'])
	{
		// Update forum info
		$sql = 'SELECT forum_last_post_time
			FROM ' . FORUMS_TABLE . '
			WHERE forum_id = ' . (int)$data['forum_id'];
		$result = $db->sql_query($sql);
		$forum_last_post_time = (int) $db->sql_fetchfield('forum_last_post_time');
		$db->sql_freeresult($result);

		update_forum_tracking_info($data['forum_id'], $forum_last_post_time, $f_mark_time, false);
	}

	// Send Notifications
	if ($mode != 'edit' && $mode != 'delete' && $post_approval)
	{
		user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id']);
	}

	$params = $add_anchor = '';

	if ($post_approval)
	{
		$params .= '&amp;t=' . $data['topic_id'];

		if ($mode != 'post')
		{
			$params .= '&amp;p=' . $data['post_id'];
			$add_anchor = '#p' . $data['post_id'];
		}
	}
	else if ($mode != 'post' && $post_mode != 'edit_first_post' && $post_mode != 'edit_topic')
	{
		$params .= '&amp;t=' . $data['topic_id'];
	}

	$url = (!$params) ? "{$phpbb_root_path}viewforum.$phpEx" : "{$phpbb_root_path}viewtopic.$phpEx";
	$url = append_sid($url, 'f=' . $data['forum_id'] . $params) . $add_anchor;

	return $url;
}

/**
* Generate Application questions
* $key is the label to use for inputs so that the form can grab the answers
*/
function generate_applys_questions($key)
{
	// global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;
	// applys configuration
	global $appc, $template;

	if (!isset($appc->applys_config['loaded']))
	{
		$appc->load_applys_config();
	}

	if (!$appc->questions_loaded)
	{
		$appc->load_questions();
	}

	$appc_qid = 0;
	$num = 1;
	if (isset($appc->applys_config['first_question_id']))
	{
		$appc_qid = $appc->applys_config['first_question_id'];
	}
	while ($appc_qid > 0)
	{
		$appc_q = $appc->applys_questions[$appc_qid];

		$input = '';
		$name = "${key}[${appc_qid}]";
		$input = generate_applys_input($name, $appc_q['type'], $appc_q['required']);
		$question = ($appc_q['required']) ? $appc_q['question'] . " *" : $appc_q['question'];
		// Is it a section?
		if ($appc_q['type'] == 1) {
			$question = '<H1>' . $question . '</H1>';
		}
		else
		{
			$question = $num . ') ' . $question;
			$num += 1;
		}

		$template->assign_block_vars('question', array(
			'QUESTION'	=> $question,
			'INPUT'		=> $input,
			));

		// Next
		$appc_qid = $appc_q['right_id'];
	}
}

/**
* Generate Application subject
* $key is the label to use for inputs so that the form can grab the answers
*/
function generate_applys_subject($key)
{
	// global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;
	// applys configuration
	global $user, $appc, $template;
	$name = '';
	$class = '';
	$role = '';

	if (!isset($appc->applys_config['loaded']))
	{
		$appc->load_applys_config();
	}

	if (!$appc->questions_loaded)
	{
		$appc->load_questions();
	}

	// Answers
	$answer_ary = utf8_normalize_nfc(request_var($key, array('' => ''), true));

	$appc_qid = 0;
	$num = 1;
	if (isset($appc->applys_config['first_question_id']))
	{
		$appc_qid = $appc->applys_config['first_question_id'];
	}
	while ($appc_qid > 0)
	{
		$appc_q = $appc->applys_questions[$appc_qid];

		$input = '';
		$type = $appc_q['type'];

		switch ($type)
		{
			case 7: // Class
				$class = $answer_ary[$appc_qid];
				break;
			case 13: // Role
				if ($role == '')
				{
					$role = $answer_ary[$appc_qid];
				}
				else
				{
					$sec_role = $answer_ary[$appc_qid];
					if ($sec_role != $user->lang('APPLY_NONE'))
					{
						$role .= '/' . $sec_role;
					}
				}
				break;
			case 15: // Character
				$name = $answer_ary[$appc_qid];
				break;
		}

		// Next
		$appc_qid = $appc_q['right_id'];
	}
	return $name.' '.$class.' '.$role;
}

/**
* Generate Application Armory Link
* $key is the label to use for inputs so that the form can grab the answers
*/
function generate_applys_armory($key)
{
	// global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;
	// applys configuration
	global $appc, $template;
	$name = '';
	$realm = '';

	if (!isset($appc->applys_config['loaded']))
	{
		$appc->load_applys_config();
	}

	if (!$appc->questions_loaded)
	{
		$appc->load_questions();
	}

	// Answers
	$answer_ary = utf8_normalize_nfc(request_var($key, array('' => ''), true));

	$appc_qid = 0;
	$num = 1;
	if (isset($appc->applys_config['first_question_id']))
	{
		$appc_qid = $appc->applys_config['first_question_id'];
	}
	while ($appc_qid > 0)
	{
		$appc_q = $appc->applys_questions[$appc_qid];

		$input = '';
		$type = $appc_q['type'];

		switch ($type)
		{
			case 15: // Character
				$name = $answer_ary[$appc_qid];
				break;
			case 16: // Realm
				$realm = $answer_ary[$appc_qid];
				break;
		}

		// Next
		$appc_qid = $appc_q['right_id'];
	}
	$region_url = applys_region_url($realm, $name);
	return $region_url;
}

/**
* Region URL
* realm
* name
*/
function applys_region_url($realm, $name)
{
	global $appc;
	// Default to US
	$region = 'US';
	$url = '';

	if ($name == '')
	{
		return $url;
	}

	if (!isset($appc->applys_config['loaded']))
	{
		$appc->load_applys_config();
	}

	if (isset($appc->applys_config['region']))
	{
		$region = $appc->applys_config['region'];
	}

	if ($realm == '')
	{
		if (isset($appc->applys_config['realm']))
		{
			$realm = $appc->applys_config['realm'];
		}
		else
		{
			return $url;
		}
	}

	switch ($region)
	{
		case 'US':
			$url = 'http://us.battle.net/wow/en/character' . '/' . $realm . '/' . $name . '/simple';
			break;
		case 'EU':
			$url = 'http://eu.battle.net/wow/en/character' . '/' . $realm . '/' . $name . '/simple';
			break;
		case 'TW':
			$url = 'http://tw.wowarmory.com/character-sheet.xml?r=' . $realm . '&cn=' . $name;
			break;
		case 'CN':
			$url = 'http://cn.wowarmory.com/character-sheet.xml?r=' . $realm . '&cn=' . $name;
			break;
		case 'KR':
			$url = 'http://kr.battle.net/wow/ko/character' . '/' . $realm . '/' . $name . '/simple';
			break;
	}
	return $url;
}

/**
* Generate Application message
* $key is the label to use for inputs so that the form can grab the answers
* $private - include private questions?
*/
function generate_applys_message($key, $private)
{
	// global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;
	// applys configuration
	global $appc, $template;
	$message = '';

	if (!isset($appc->applys_config['loaded']))
	{
		$appc->load_applys_config();
	}

	if (!$appc->questions_loaded)
	{
		$appc->load_questions();
	}

	// Armory link
	$message .= generate_applys_armory($key) . "\n\n";

	// Answers
	$answer_ary = utf8_normalize_nfc(request_var($key, array('' => ''), true));

	$appc_qid = 0;
	$num = 1;
	if (isset($appc->applys_config['first_question_id']))
	{
		$appc_qid = $appc->applys_config['first_question_id'];
	}
	while ($appc_qid > 0)
	{
		$appc_q = $appc->applys_questions[$appc_qid];

		$input = '';
		$question = ($appc_q['required']) ? $appc_q['question'] . " *" : $appc_q['question'];
		// Is it a section?
		if ($appc_q['type'] == 1)
		{
			$message .= "\n[color=#FF0000][size=125]" . $question . "[/size][/color]\n";
		}
		// Private
		else if ($appc_q['type'] == 9)
		{
			$answer = $answer_ary[$appc_qid];
			if ($answer == -1)
			{
				$answer = '';
			}
			if ($private)
			{
				$message .= '[color=#FFFF00]' . $num . ') ' . $question . ' [/color] : ' . $answer . "\n";
				$num += 1;
			}
		}
		else
		{
			$answer = $answer_ary[$appc_qid];
			if ($answer == -1)
			{
				$answer = '';
			}
			$message .= '[color=#FFFF00]' . $num . ') ' . $question . ' [/color] : ' . $answer . "\n";
			$num += 1;
		}

		// Next
		$appc_qid = $appc_q['right_id'];
	}

	// If private, also include the e-mail address
	if ($private)
	{
		$email = request_var('email', '');
		$message .= '[color=#FFFF00]E-mail[/color] : ' . $email . "\n";
	}

	return $message;
}

/**
* Generate Validation checks
* $key is the label to use for inputs so that the form can grab the answers
*/
function generate_validation_questions($key)
{
	// global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;
	// applys configuration
	global $appc, $template;
	$vars = '';
	$checks = '';

	if (!isset($appc->applys_config['loaded']))
	{
		$appc->load_applys_config();
	}

	if (!$appc->questions_loaded)
	{
		$appc->load_questions();
	}

	$appc_qid = 0;
	$num = 1;
	if (isset($appc->applys_config['first_question_id']))
	{
		$appc_qid = $appc->applys_config['first_question_id'];
	}
	while ($appc_qid > 0)
	{
		$appc_q = $appc->applys_questions[$appc_qid];

		$input = '';
		$name = "${key}[${appc_qid}]";
		$required = $appc_q['required'];
		$type = $appc_q['type'];

		if ($required) {
			// Not all types are checked yet
			switch ($type)
			{
				case 3: // Text
				case 4: // Text Area
				case 5: // Yes/No
				case 9: // Private
				case 15: // Character
				case 16: // Realm
					$vars .= "\t\tvar q" . $num . " = document.getElementById('" . $name . "');\n";
					$checks .= "\t\tif(!(notEmpty(q" . $num .
						', "You must answer question '. $num . '"))){' .
						"\n\t\t\treturn false;\n" . "\t\t}\n";
					break;
				case 6: // Race
				case 7: // Class
				case 8: // Profession
				case 10: // Timezone
				case 11: // Skill level
				case 13: // Role
					$vars .= "\t\tvar q" . $num . " = document.getElementById('" . $name . "');\n";
					$checks .= "\t\tif(!(isSelected(q" . $num .
						', "You must answer question '. $num . '"))){' .
						"\n\t\t\treturn false;\n" . "\t\t}\n";
					break;
			}
		}

		// Next
		$appc_qid = $appc_q['right_id'];
		// If it is a section we don't increment the question count
		if ($appc_q['type'] != 1) {
			$num += 1;
		}
	}
	return $vars . "\n" . $checks;
}

/**
* Return an input string of the given type
*/
function generate_applys_input($name, $type, $required)
{
	global $tabindex;
	$input = '';

	switch ($type)
	{
		case 1: // Section
			break;
		case 2: // Statement
			break;
		case 3: // Text
			$input = '<input style="width:350px" type="text" id="'. $name .'" name="'. $name . '" size="80" maxlength="200" tabindex="' . $tabindex .'" />';
			$tabindex += 1;
			break;
		case 4: // Text Area
			$input = '<textarea id="'. $name . '"name="'. $name . '" rows="3" cols="76" tabindex="'. $tabindex .'" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" style="width: 350px;"></textarea>';
			$tabindex += 1;
			break;
		case 5: // Yes/No
			$input = applys_radio_yesno($name);
			$tabindex += 1;
			break;
		case 6: // Race
			$input = applys_select_race($name);
			$tabindex += 1;
			break;
		case 7: // Class
			$input = applys_select_class($name);
			$tabindex += 1;
			break;
		case 8: // Profession
			$input = applys_select_profession($name);
			$tabindex += 1;
			break;
		case 9: // Private (Only posted to second forum)
			$input = '<textarea id="'. $name . '"name="'. $name . '" rows="3" cols="76" tabindex="'. $tabindex .'" onselect="storeCaret(this);" onclick="storeCaret(this);" onkeyup="storeCaret(this);" style="width: 350px;"></textarea>';
			$tabindex += 1;
			break;
		case 10: // Timezone
			$input = applys_select_tz($name);
			$tabindex += 1;
			break;
		case 11: // Skill
			$input = applys_select_skill($name);
			$tabindex += 1;
			break;
		case 12: // Days per Week
			$input = applys_select_daysperweek($name);
			$tabindex += 1;
			break;
		case 13: // Role
			$input = applys_select_role($name);
			$tabindex += 1;
			break;
		case 14: // Select Days
			$input = applys_select_days($name);
			$tabindex += 1;
			break;
		case 15: // Character
			$input = '<input style="width:350px" type="text" id="'. $name .'" name="'. $name . '" size="80" maxlength="200" tabindex="' . $tabindex .'" />';
			$tabindex += 1;
			break;
		case 16: // Realm
			$input = '<input style="width:350px" type="text" id="'. $name .'" name="'. $name . '" size="80" maxlength="200" tabindex="' . $tabindex .'" />';
			$tabindex += 1;
			break;
	}
	return $input;
}

/**
* Radio button yes/no input
*/
function applys_radio_yesno($name)
{
	global $user, $tabindex;
	return '<input type="radio" name="' . $name .'" id="' . $name . 
		'" tabindex="' . $tabindex .'" value="YES" />' .
		$user->lang('YES') . '&nbsp;' .
		'<input type="radio" name="' . $name .'" id="' . $name . 
		'" tabindex="' . $tabindex .'" value="NO" />' .
		$user->lang('NO');
}

/**
* Select box race input
*/
function applys_select_race($name)
{
	global $appc, $user, $tabindex;
	$input = '';

	$faction = $appc->applys_config['faction'];
	$input = '<select id="'. $name .'" name="'. $name .
		'" tabindex="' . $tabindex . '">' .
		'<option value="-1">' . $user->lang('APPLY_SELECT_RACE');

	for ($i = 1; $i <= 6; $i++)
	{
		$value = applys_get_race($faction, $i);
		$input .= '<option value="' . $value . '">' . $value;
	}

	$input .= '</select>';

	return $input;
}

/**
* Get race by value
*/
function applys_get_race($faction, $value)
{
	global $user;

	$race = '';
	if ($faction == $user->lang('APPLY_HORDE'))
	{
		switch ($value)
		{
			case 1:
				$race = $user->lang('BLOODELF');
				break;
			case 2:
				$race = $user->lang('GOBLIN');
				break;
			case 3:
				$race = $user->lang('ORC');
				break;
			case 4:
				$race = $user->lang('TAUREN');
				break;
			case 5:
				$race = $user->lang('TROLL');
				break;
			case 6:
				$race = $user->lang('UNDEAD');
				break;
		}
	}
	else
	{
		switch ($value)
		{
			case 1:
				$race = $user->lang('DRAENEI');
				break;
			case 2:
				$race = $user->lang('DWARF');
				break;
			case 3:
				$race = $user->lang('GNOME');
				break;
			case 4:
				$race = $user->lang('HUMAN');
				break;
			case 5:
				$race = $user->lang('NIGHTELF');
				break;
			case 6:
				$race = $user->lang('WORGEN');
				break;
		}
	}
	return $race;
}

/**
* Select box class input
*/
function applys_select_class($name)
{
	global $user, $tabindex;
	$input = '';

	$input = '<select id="'. $name .'" name="'. $name .
		'" tabindex="' . $tabindex . '">' .
		'<option value="-1">' . $user->lang('APPLY_SELECT_CLASS');

	for ($i = 1; $i <= 10; $i++)
	{
		$value = applys_get_class($i);
		$input .= '<option value="' . $value . '">' . $value;
	}

	$input .= '</select>';

	return $input;
}

/**
* Get class by value
*/
function applys_get_class($value)
{
	global $user;

	$class = '';

	switch ($value)
	{
		case 1:
			$class = $user->lang('DEATHKNIGHT');
			break;
		case 2:
			$class = $user->lang('DRUID');
			break;
		case 3:
			$class = $user->lang('HUNTER');
			break;
		case 4:
			$class = $user->lang('MAGE');
			break;
		case 5:
			$class = $user->lang('PALADIN');
			break;
		case 6:
			$class = $user->lang('PRIEST');
			break;
		case 7:
			$class = $user->lang('ROGUE');
			break;
		case 8:
			$class = $user->lang('SHAMAN');
			break;
		case 9:
			$class = $user->lang('WARLOCK');
			break;
		case 10:
			$class = $user->lang('WARRIOR');
			break;
	}
	return $class;
}

/**
* Select box profession input
*/
function applys_select_profession($name)
{
	global $user, $tabindex;
	$input = '';

	$input = '<select id="'. $name .'" name="'. $name .
		'" tabindex="' . $tabindex . '">' .
		'<option value="-1">' . $user->lang('APPLY_SELECT_PROFESSION');

	for ($i = 1; $i <= 11; $i++)
	{
		$value = applys_get_profession($i);
		$input .= '<option value="' . $value . '">' . $value;
	}

	$input .= '</select>';

	return $input;
}

/**
* Get profession by value
*/
function applys_get_profession($value)
{
	global $user;

	$prof = '';

	switch ($value)
	{
		case 1:
			$prof = $user->lang('ALCHEMY');
			break;
		case 2:
			$prof = $user->lang('BLACKSMITHING');
			break;
		case 3:
			$prof = $user->lang('ENCHANTING');
			break;
		case 4:
			$prof = $user->lang('ENGINEERING');
			break;
		case 5:
			$prof = $user->lang('HERBALISM');
			break;
		case 6:
			$prof = $user->lang('INSCRIPTION');
			break;
		case 7:
			$prof = $user->lang('JEWELCRAFTING');
			break;
		case 8:
			$prof = $user->lang('LEATHERWORKING');
			break;
		case 9:
			$prof = $user->lang('MINING');
			break;
		case 10:
			$prof = $user->lang('SKINNING');
			break;
		case 11:
			$prof = $user->lang('TAILORING');
			break;
	}

	return $prof;
}

/**
* Select box timezone input
*/
function applys_select_tz($name)
{
	global $user, $tabindex;
	$input = '';

	$input = '<select id="'. $name .'" name="'. $name .
		'" tabindex="' . $tabindex . '">' .
		'<option value="-1">' . $user->lang('APPLY_SELECT_TIMEZONE');

	$input .= tz_select();

	$input .= '</select>';

	return $input;
}

/**
* Select box timezone input
*/
function applys_select_skill($name)
{
	global $user, $tabindex;
	$input = '';

	$input = '<select id="'. $name .'" name="'. $name .
		'" tabindex="' . $tabindex . '">' .
		'<option value="-1">' . $user->lang('APPLY_SELECT_SKILL');

	for ($i = 1; $i <= 4; $i++)
	{
		$value = applys_get_skill($i);
		$input .= '<option value="' . $value . '">' . $value;
	}

	$input .= '</select>';

	return $input;
}

/**
* Get skill level by value
*/
function applys_get_skill($value)
{
	global $user;

	$skill = '';

	switch ($value)
	{
		case 1:
			$skill = $user->lang('APPLY_POOR');
			break;
		case 2:
			$skill = $user->lang('APPLY_MODERATE');
			break;
		case 3:
			$skill = $user->lang('APPLY_GOOD');
			break;
		case 4:
			$skill = $user->lang('APPLY_EXCELLENT');
			break;
	}

	return $skill;
}

/**
* Select box days per week input
*/
function applys_select_daysperweek($name)
{
	global $user, $tabindex;
	$input = '';

	$input = '<select id="'. $name .'" name="'. $name .
		'" tabindex="' . $tabindex . '">';

	for ($i = 0; $i <= 7; $i++)
	{
		$input .= '<option value="' . $i . '">' . $i;
	}

	$input .= '</select>';

	return $input;
}

/**
* Select box role input
*/
function applys_select_role($name)
{
	global $user, $tabindex;
	$input = '';

	$input = '<select id="'. $name .'" name="'. $name .
		'" tabindex="' . $tabindex . '">' .
		'<option value="-1">' . $user->lang('APPLY_SELECT_ROLE');

	for ($i = 1; $i <= 9; $i++)
	{
		$value = applys_get_role($i);
		$input .= '<option value="' . $value . '">' . $value;
	}

	$input .= '</select>';

	return $input;
}

/**
* Get role by value
*/
function applys_get_role($value)
{
	global $user;

	$role = '';

	switch ($value)
	{
		case 1:
			$role = $user->lang('APPLY_PVE_TANK');
			break;
		case 2:
			$role = $user->lang('APPLY_PVE_HEALER');
			break;
		case 3:
			$role = $user->lang('APPLY_PVE_MELEE');
			break;
		case 4:
			$role = $user->lang('APPLY_PVE_RANGED');
			break;
		case 5:
			$role = $user->lang('APPLY_PVP_TANK');
			break;
		case 6:
			$role = $user->lang('APPLY_PVP_HEALER');
			break;
		case 7:
			$role = $user->lang('APPLY_PVP_MELEE');
			break;
		case 8:
			$role = $user->lang('APPLY_PVP_RANGED');
			break;
		case 9:
			$role = $user->lang('APPLY_NONE');
			break;
	}

	return $role;
}

/**
* Select box days input
*/
function applys_select_days($name)
{
	global $user, $tabindex;
	$input = '';

	for ($i = 1; $i <= 7; $i++)
	{
		$value = applys_get_day($i);
		$input .= '<input type="checkbox" id = "' . $name . '" name ="' . $name .
			'" value = "' . $value .
			'" tabindex="' . $tabindex . '">' . $value . '<BR>';
	}

	return $input;
}

/**
* Get day by value
*/
function applys_get_day($value)
{
	global $user;

	$day = '';

	switch ($value)
	{
		case 1:
			$day = $user->lang['datetime']['Sunday'];
			break;
		case 2:
			$day = $user->lang['datetime']['Monday'];
			break;
		case 3:
			$day = $user->lang['datetime']['Tuesday'];
			break;
		case 4:
			$day = $user->lang['datetime']['Wednesday'];
			break;
		case 5:
			$day = $user->lang['datetime']['Thursday'];
			break;
		case 6:
			$day = $user->lang['datetime']['Friday'];
			break;
		case 7:
			$day = $user->lang['datetime']['Saturday'];
			break;
	}
	return $day;
}

?>
